home *** CD-ROM | disk | FTP | other *** search
/ Aminet 32 / Aminet 32 (1999)(Schatztruhe)[!][Aug 1999].iso / Aminet / util / libs / graphics3d.lha / src / library / graphics3Df_i.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-28  |  18.0 KB  |  779 lines

  1. /*
  2. **      $VER: graphics3Df_i.c 10.10 (16.02.98)
  3. **
  4. **      Internal functions for graphics3D.library
  5. **
  6. **      (C) Copyright 97 Patrizio Biancalani
  7. **      All Rights Reserved.
  8. **
  9. **    Note: this code is traslate from the blitzbasic 3d graphics engine 
  10. **          V 0.9 of Maciej R. Gorny.
  11. */
  12.  
  13. #include <exec/types.h>
  14. #include <exec/memory.h>
  15. #include <proto/exec.h>
  16. #include <proto/intuition.h>
  17. #include <intuition/intuition.h>
  18. #include <intuition/screens.h>
  19.  
  20. #include <graphics/rastport.h>
  21. #include <graphics/clip.h>
  22. #include <graphics/regions.h>
  23. #include <graphics/gfx.h>
  24. #include <graphics/gfxmacros.h>
  25. #include <graphics/layers.h>
  26.  
  27. #include "graphics3Dc.h"
  28. #include "graphics3D.h"
  29. #include "graphics3d2d.h"
  30. #include "graphics3d2d_proto.h"
  31.  
  32. /** prototipi locali **/
  33. struct objectnode *resetobj(struct ambient3d *in);
  34. struct objectnode *nextobj(struct ambient3d *in);
  35. struct objectnode *pobj(struct ambient3d *in);
  36.  
  37. /*** funzioni esterne solo matematiche ***/
  38. extern void matidentity4x4(struct matrix4x4 *imatrix); 
  39. extern void matzero4x4(struct matrix4x4 imatrix);
  40. extern void matcopy4x4(struct matrix4x4 *s_m,struct matrix4x4 *d_m);
  41. extern void matmult4x4(struct matrix4x4 *a,struct matrix4x4 *b,
  42.         struct matrix4x4 *r);
  43. extern void matmult4x4s(struct matrix4x4 *a,struct matrix4x4 *b,
  44.         struct matrix4x4 *r);
  45. extern void matmult1x4s(struct matrix1x4 *a,struct matrix4x4 *b,
  46.         struct matrix1x4 *r);
  47. extern void makevector3d(struct vertex *a,struct vertex *b,
  48.          struct vector *result);
  49. extern long int vectormag3d(struct vector *a);
  50. extern void normalpol(struct vertex *v0,struct vertex *v1,
  51.      struct vertex *v2,struct vector *normal);
  52. extern long int dotproduct(struct vector *u,struct vector *v);
  53. extern long int sqri(long int v);
  54. extern long int abs(long int val);
  55.  
  56. /************************************/
  57. /* costruzione tavole seno e coseno */
  58. /************************************/
  59. void buildlookuptables(in)
  60. struct ambient3d *in;
  61. {
  62. long int *sn,*cn,i,ii;
  63. long int t[]=
  64. {    
  65. /** val. seno angolo (0,90) e moltiplicato per 256 **/
  66.     0,4,9,13,17,22,26,30,35,39,43,47,52,
  67.     56,60,65,69,73,77,81,85,89,93,98,101,105,
  68.     109,113,117,121,125,129,132,136,140,143,
  69.     147,151,154,157,161,164,167,171,174,177,
  70.     180,183,186,189,192,195,198,200,203,206,
  71.     208,211,213,216,218,220,222,225,227,229,
  72.     230,232,234,236,238,239,241,242,243,245,
  73.     246,247,248,249,250,251,252,253,253,254,
  74.     254,255,255,255,256
  75. };
  76.  
  77. /*
  78. #ifdef DEBUG
  79. char dbg[80];
  80. #endif
  81. */
  82.  
  83. sn=in->sintable;
  84. cn=in->costable;
  85. /** val. seno angolo (0,90) e moltiplicato per 1024 **/
  86. /*
  87. t:=[0,17,35,53,71,89,
  88.     106,124,142,160,177,195,212,230,247,264,282,299,
  89.     316,333,350,366,383,399,416,432,448,464,480,496,
  90.     511,527,542,557,572,587,601,615,630,644,657,671,
  91.     684,698,711,723,736,748,760,772,784,795,806,817,
  92.     828,838,848,858,868,877,886,895,903,912,920,927,
  93.     935,942,949,955,962,968,973,979,984,988,993,997,
  94.     1001,1005,1008,1011,1013,1016,1018,1020,1021,1022,
  95.     1023,1023,1024]:LONG
  96. */
  97. ii=0;
  98. for(i=0; i<361; i++)
  99.     {
  100.     if (i<91)
  101.         {
  102.         sn[i]=t[ii];
  103.         cn[i]=t[90-ii];
  104.         }
  105.     else if (i<181) 
  106.         {
  107.         sn[i]=t[90-ii];
  108.         cn[i]=-t[ii];
  109.         }
  110.     else if (i<271)
  111.         {
  112.         sn[i]=-t[ii];
  113.         cn[i]=-t[90-ii];
  114.         }
  115.     else
  116.         {
  117.         sn[i]=-t[90-ii];
  118.         cn[i]=t[ii];
  119.         }
  120. /*
  121. #ifdef DEBUG
  122. sprintf(dbg,"t[%ld]=%ld sn[%ld]=%ld cn[%ld]=%ld\n",ii,t[ii],i,sn[i],i,cn[i]);
  123. write_dbg(dbg);
  124. #endif
  125. */
  126.     ii++;
  127.     if (ii>90) ii=1;
  128.     }
  129. }
  130.  
  131. /*******************************************************/
  132. /** crea la matrice di trasformazione inversa globale **/
  133. /** usata per passare da coordinate del mondo in      **/
  134. /** coordinate della camera                  **/
  135. /** Crea matrice in.global_view per capirci.          **/
  136. /*******************************************************/
  137. void createworldtocamera(in)
  138. struct ambient3d *in;
  139. {
  140. long int temp,active_axes;
  141. struct matrix4x4 translate,rotate_x,rotate_y,rotate_z;
  142. struct matrix4x4 result_1,result_2,*g_v;
  143. struct vector *v_p;
  144. struct dir3d *v_a;
  145. long int *cos,*sin;
  146.  
  147. cos=in->costable;
  148. sin=in->sintable;
  149. v_a=&in->view_angle;
  150. v_p=&in->view_point;
  151. g_v=&in->global_view;
  152.  
  153. active_axes=0;
  154.  
  155. matidentity4x4(&translate);
  156. translate.r3c0=-v_p->x;
  157. translate.r3c1=-v_p->y;
  158. translate.r3c2=-v_p->z;
  159.  
  160. if (v_a->angx!=NULL AND v_a->angx!=360)
  161.     {
  162.     matidentity4x4(&rotate_x);
  163.     rotate_x.r1c1=cos[v_a->angx];
  164.     rotate_x.r1c2=sin[v_a->angx];
  165.     rotate_x.r2c1=-sin[v_a->angx];
  166.     rotate_x.r2c2=cos[v_a->angx];
  167.     active_axes=active_axes+1;
  168.     }
  169.  
  170. if (v_a->angy!=NULL AND v_a->angy!=360)
  171.     {
  172.     matidentity4x4(&rotate_y);
  173.     rotate_y.r0c0=cos[v_a->angy];
  174.     rotate_y.r0c2=sin[v_a->angy];
  175.     rotate_y.r2c0=-sin[v_a->angy];
  176.     rotate_y.r2c2=cos[v_a->angy];
  177.     active_axes=active_axes+2;
  178.     }
  179.  
  180. if (v_a->angz!=NULL AND v_a->angz!=360)
  181.     {
  182.     matidentity4x4(&rotate_z);
  183.     rotate_z.r0c0=cos[v_a->angz];
  184.     rotate_z.r0c1=sin[v_a->angz];
  185.     rotate_z.r1c0=-sin[v_a->angz];
  186.     rotate_z.r1c1=cos[v_a->angz];
  187.     active_axes=active_axes+4;
  188.     }
  189.  
  190. switch (active_axes)
  191.     {
  192.     case (0):
  193.         matcopy4x4(&translate,g_v);
  194.         break;
  195.  
  196.     case (1):
  197.         matmult4x4s(&translate,&rotate_x,g_v);
  198. /*
  199.         matcopy4x4(&rotate_x,g_v);
  200.         g_v->r3c0=-v_p->x;
  201.         temp=-v_p->y*cos[v_a->angx] + v_p->z*sin[v_a->angx];
  202.         g_v->r3c1=temp >> SFIXV;
  203.         temp=v_p->y*sin[v_a->angx] - v_p->z*cos[v_a->angx];
  204.         g_v->r3c2=temp >> SFIXV;
  205. */
  206.         break;
  207.  
  208.     case (2):
  209.         matmult4x4s(&translate,&rotate_y,g_v);
  210. /*
  211.         matcopy4x4(&rotate_y,g_v);
  212.         temp=-v_p->x*cos[v_a->angy]+v_p->z*sin[v_a->angy];
  213.         g_v->r3c0=temp >> SFIXV;
  214.         g_v->r3c1=-v_p->y;
  215.         temp=-v_p->x*sin[v_a->angy]-v_p->z*cos[v_a->angy];
  216.         g_v->r3c2=temp >> SFIXV;
  217. */
  218.         break;
  219.  
  220.     case (3):
  221.         matmult4x4s(&translate,&rotate_x,&result_1);
  222.         matmult4x4s(&result_1,&rotate_y,g_v);
  223.         break;
  224.  
  225.     case (4):
  226.         matmult4x4s(&translate,&rotate_z,g_v);
  227. /*
  228.         matcopy4x4(&rotate_z,g_v);
  229.         temp=v_p->x*cos[v_a->angz]-v_p->y*sin[v_a->angz];
  230.         g_v->r3c0=temp >> SFIXV;
  231.         temp=-v_p->x*sin[v_a->angz]-v_p->y*cos[v_a->angz];
  232.         g_v->r3c1=temp >> SFIXV;
  233.         g_v->r3c3=-v_p->z;
  234. */
  235.         break;
  236.  
  237.     case (5):
  238.         matmult4x4s(&translate,&rotate_x,&result_1);
  239.         matmult4x4s(&result_1,&rotate_z,g_v);
  240.         break;
  241.  
  242.     case (6):
  243.         matmult4x4s(&translate,&rotate_y,&result_1);
  244.         matmult4x4s(&result_1,&rotate_z,g_v);
  245.         break;
  246.  
  247.     case (7):
  248.         matmult4x4s(&translate,&rotate_x,&result_1);
  249.         matmult4x4s(&result_1,&rotate_y,&result_2);
  250.         matmult4x4s(&result_2,&rotate_z,g_v);
  251.         
  252.     }
  253. }
  254.  
  255. /*******************************************************
  256.  ** trasla le coordinate locali dell'oggetto corrente **
  257.  ** nelle coordinate del mondo                   **
  258.  *******************************************************
  259.  *** INPUT :                           * 
  260.  * in -> valore > 0 restituito da display3d.           *
  261.  *** OUTPUT:                           *
  262.  * nessuno.                           *
  263.  *******************************************************/
  264. void localtoworld(in)
  265. struct ambient3d *in;
  266. {
  267. struct objectnode *obj;
  268. long int index;
  269. struct vertex *vl;
  270. struct vert1 *vg;
  271. struct polygon *pl;
  272. long int wx,wy,wz;
  273.  
  274. obj=pobj(in);
  275. vg=obj->vcamera;
  276. vl=obj->vlocal;
  277. pl=obj->polys;
  278. wx=obj->worldposx;
  279. wy=obj->worldposy;
  280. wz=obj->worldposz;
  281. for (index=0; index<obj->numverts; index++)
  282.     {
  283.     vg[index].x=vl[index].x+wx;
  284.     vg[index].y=vl[index].y+wy;
  285.     vg[index].z=vl[index].z+wz;
  286.     }
  287. /* resetta flag di invisibilita' */
  288. for (index=0; index<obj->numpolys; index++)
  289.     {
  290.     pl[index].visible=1;
  291.     pl[index].clipped=0;
  292.     }
  293. }
  294.  
  295. /***************************************************
  296.  ** converte le coordinate nel mondo dell'oggetto **
  297.  ** corrente nelle coordinate della camera        **
  298.  ***************************************************
  299.  *** INPUT :                        * 
  300.  * in -> valore > 0 restituito da display3d.       *
  301.  *** OUTPUT:                       *
  302.  * nessuno.                       *
  303.  ***************************************************/
  304. void worldtocamera(in)
  305. struct ambient3d *in;
  306. {
  307. struct objectnode *obj;
  308. long int index,temp,tempx,tempy,tempz,active_axes;
  309. struct vert1 *vc;
  310. struct matrix4x4 gv,*g_v;
  311. struct dir3d *vang;
  312.  
  313. obj=pobj(in);
  314. vc=obj->vcamera;
  315. vang=&in->view_angle;
  316. g_v=&in->global_view;
  317.  
  318. active_axes=0;
  319.  
  320. if (vang->angx!=NULL) active_axes=active_axes+1; 
  321. if (vang->angy!=NULL) active_axes=active_axes+2;
  322. if (vang->angz!=NULL) active_axes=active_axes+4;
  323.  
  324. switch (active_axes)
  325.     {
  326.     case (0):
  327.         for (index=0; index<obj->numverts; index++)
  328.             {    
  329.             vc[index].x=vc[index].x+g_v->r3c0;
  330.             vc[index].y=vc[index].y+g_v->r3c1;
  331.             vc[index].z=vc[index].z+g_v->r3c2;
  332.             }
  333.         break;
  334.     case (1):
  335.         for (index=0; index<obj->numverts; index++)
  336.             {    
  337.             vc[index].x=vc[index].x+g_v->r3c0;
  338.             tempy=vc[index].y*g_v->r1c1+vc[index].z*g_v->r2c1;
  339.             tempz=vc[index].y*g_v->r1c2+vc[index].z*g_v->r2c2;
  340.             vc[index].z=(tempz >> SFIXV)+g_v->r3c2;
  341.             vc[index].y=(tempy >> SFIXV)+g_v->r3c1;
  342.             }
  343.         break;
  344.  
  345.     case (2):
  346.         for (index=0; index<obj->numverts; index++)
  347.             {    
  348.             tempx=vc[index].x*g_v->r0c0+vc[index].z*g_v->r2c0;
  349.             tempz=vc[index].x*g_v->r0c2+vc[index].z*g_v->r2c2;
  350.             vc[index].y=vc[index].y+g_v->r3c1;
  351.             vc[index].z=(tempz >> SFIXV)+g_v->r3c2;
  352.             vc[index].x=(tempx >> SFIXV)+g_v->r3c0;
  353.             }
  354.         break;
  355.  
  356.     case (4):
  357.         for (index=0; index<obj->numverts; index++)
  358.             {    
  359.             tempx=vc[index].x*g_v->r0c0+vc[index].y*g_v->r1c0;
  360.             tempy=vc[index].x*g_v->r0c1+vc[index].y*g_v->r1c1;
  361.             vc[index].y=(tempy >> SFIXV)+g_v->r3c1;
  362.             vc[index].x=(tempx >> SFIXV)+g_v->r3c0;
  363.             vc[index].z=vc[index].z+g_v->r3c2;
  364.             }
  365.         break;
  366.  
  367.     default :
  368.         for (index=0; index<obj->numverts; index++)
  369.             {    
  370.             tempx=vc[index].x*g_v->r0c0+vc[index].y*g_v->r1c0+
  371.                 vc[index].z*g_v->r2c0;
  372.             tempy=vc[index].x*g_v->r0c1+vc[index].y*g_v->r1c1+
  373.                 vc[index].z*g_v->r2c1;        
  374.             tempz=vc[index].x*g_v->r0c2+vc[index].y*g_v->r1c2+
  375.                 vc[index].z*g_v->r2c2;        
  376.             vc[index].x=(tempx >> SFIXV)+g_v->r3c0;
  377.             vc[index].y=(tempy >> SFIXV)+g_v->r3c1;
  378.             vc[index].z=(tempz >> SFIXV)+g_v->r3c2;
  379.             }
  380.     }    
  381. }
  382.  
  383. /**********************************************
  384.  ** riporto oggetto attuale sul primo e      **
  385.  ** resituisco puntatore a oggetto.          **
  386.  **********************************************
  387.  *** INPUT :                      * 
  388.  * in -> valore > 0 restituito da display3d.  *
  389.  *** OUTPUT:                      *
  390.  * puntatore a struttura 1# oggetto.          *
  391.  **********************************************/
  392. struct objectnode *resetobj(in)
  393. struct ambient3d *in;
  394. {
  395.  
  396. in->attuale=0;
  397.  
  398. return (pobj(in));
  399. }
  400.  
  401. /**********************************************
  402.  ** sposto oggetto attuale su prossimo se    **
  403.  ** finiti restituisco 0 altrimenti puntore  **
  404.  ** a oggetto.                     **
  405.  **********************************************
  406.  *** INPUT :                      * 
  407.  * in -> valore > 0 restituito da display3d.  *
  408.  *** OUTPUT:                      *
  409.  * >0 - puntatore a oggetto successivo.       *
  410.  * =0 - oggetti finiti.                  *
  411.  **********************************************/
  412. struct objectnode *nextobj(in)
  413. struct ambient3d *in;
  414. {
  415.  
  416. if (in->total_objects==NULL) return(0);
  417. if (in->attuale>=in->total_objects-1) return(0); 
  418.  
  419. in->attuale=in->attuale+1;
  420.  
  421. return (pobj(in));
  422.  
  423. /*******************************************
  424.  ** restituisce indirizzo oggetto attuale **
  425.  ** o 0 se nessun oggetto presente.       **
  426.  *******************************************/
  427.  
  428. struct objectnode *pobj(in)
  429. struct ambient3d *in;
  430. {
  431.  
  432. if (in->total_objects==NULL) return(0);
  433.  
  434. return(&in->objects[in->attuale]);
  435.  
  436. }
  437.  
  438. /************************************************
  439.  ** aggiorna tutti i valori precalcolati sul   **
  440.  ** oggetto corrente.                     **
  441.  ************************************************
  442.  *** INPUT :                        * 
  443.  * in -> valore > 0 restituito da display3d.    *
  444.  *** OUTPUT:                    *
  445.  * nessuno.                    *
  446.  ************************************************/
  447. void aggobj(in)
  448. struct ambient3d *in;
  449. {
  450.  
  451. computeobjectbox(in);
  452.  
  453. }
  454.  
  455. /**********************************************/
  456. /** calcola il bounding box dell'oggetto at- **/
  457. /** tuale per il controllo delle collisioni  **/
  458. /**********************************************/
  459. void computeobjectbox(in)
  460. struct ambient3d *in;
  461. {
  462. struct objectnode *ob;
  463. struct vertex *vt;
  464. long int xmax,ymax,zmax,xmin,ymin,zmin;
  465. long int x,y,z,i;
  466.  
  467. ob=pobj(in);
  468.  
  469. vt=ob->vlocal;
  470.  
  471. xmax=-2147483645;
  472. ymax=-2147483645;
  473. zmax=-2147483645;
  474. xmin=2147483645;
  475. ymin=2147483645;
  476. zmin=2147483645;
  477.  
  478. for(i=0 ;i<ob->numverts ; i++)
  479.     {
  480.     x=vt[i].x;
  481.     y=vt[i].y;
  482.     z=vt[i].z;
  483.     if (x>xmax) xmax=x;
  484.     if (x<xmin) xmin=x;
  485.     if (y>ymax) ymax=y;
  486.     if (y<ymin) ymin=y;
  487.     if (z>zmax) zmax=z;
  488.     if (z<zmin) zmin=z;
  489.     }
  490.  
  491. ob->xmax=xmax;
  492. ob->ymax=ymax;
  493. ob->zmax=zmax;
  494. ob->xmin=xmin;
  495. ob->ymin=ymin;
  496. ob->zmin=zmin;
  497.  
  498. }
  499.  
  500. /*****************************************************/
  501. /** determina se l'intero oggetto corrente e' fuori **/
  502. /** dal volume compreso nella visuale o inattivo.   **/
  503. /** Se si rimosso ,ritorna un valore <>0        **/
  504. /*****************************************************/
  505. long int t_removeobject(in)
  506. struct ambient3d *in;
  507. {
  508. long int n_z,f_z;
  509. long int zvd,temp,x_bsphere,y_bsphere,z_bsphere;
  510. long int xmax,ymax,zmax,xmin,ymin,zmin,x_compare,y_compare;
  511. struct objectnode *obj;
  512. struct matrix4x4 *g_v;
  513.  
  514. #ifdef DEBUG
  515. char dbg[100];
  516. #endif
  517.  
  518. /* trasformo da interi a fixpoint */
  519. f_z=in->far_z * FIXV;
  520. n_z=in->near_z * FIXV;
  521.  
  522. zvd=(in->viewing_distance*in->zoom)>>SFIXV;
  523.  
  524. obj=pobj(in);
  525. g_v=&in->global_view;
  526.  
  527. /* test se oggetto disattivato ,quindi invisibile */
  528. if (!obj->state) return(1);
  529.     
  530. /* segnalo oggetto non clippato per default */
  531. obj->clipped=0;
  532.  
  533. xmax=obj->xmax;
  534. ymax=obj->ymax;
  535. zmax=obj->zmin;
  536. xmin=obj->xmin;
  537. ymin=obj->ymin;
  538. zmin=obj->zmax;
  539.  
  540. temp=obj->worldposx*g_v->r0c0 + obj->worldposy*g_v->r1c0 +
  541.     obj->worldposz*g_v->r2c0;
  542. x_bsphere=(temp>>SFIXV) + g_v->r3c0;
  543. temp=obj->worldposx*g_v->r0c1 + obj->worldposy*g_v->r1c1 +
  544.       obj->worldposz*g_v->r2c1;
  545. y_bsphere=(temp>>SFIXV) + g_v->r3c1;
  546. temp=obj->worldposx*g_v->r0c2 + obj->worldposy*g_v->r1c2 +
  547.       obj->worldposz*g_v->r2c2;
  548. z_bsphere=(temp>>SFIXV) + g_v->r3c2;
  549.  
  550. /* clip con bounding box */
  551. if (in->clip_mode==ZPLANE)
  552.     {
  553.     if (z_bsphere+zmax>f_z OR z_bsphere+zmin<n_z) 
  554.         {
  555.         obj->clipped=1;
  556.         return(2);
  557.         }
  558.     else
  559.         {
  560.         return(0);
  561.         }    
  562.     }
  563. else   
  564.     {
  565.     /* esegue un completo test su XYZ */
  566.     if ((z_bsphere+zmax)>f_z OR (z_bsphere+zmin)<n_z)
  567.         {
  568.         obj->clipped=1;
  569.         return(3);
  570.         }
  571.     temp=in->half_screen_width*z_bsphere;
  572.     x_compare=temp/zvd;
  573.     if ((x_bsphere+xmin)>x_compare OR (x_bsphere+xmax)<-x_compare)
  574.         {
  575.         obj->clipped=1;
  576.         return(4);
  577.         }
  578.     temp=(in->half_screen_height*z_bsphere)/zvd;
  579.     y_compare=(temp*in->inv_aspect_ratio) >> SFIXV;
  580.     if ((y_bsphere+ymin)>y_compare OR (y_bsphere+ymax)<-y_compare)
  581.         {
  582.         obj->clipped=1;
  583.         return(5);
  584.         }
  585.     }
  586.  
  587. return(0);
  588. }
  589.  
  590. /****************************************************/
  591. /** clippa le coordinate della camera dell'oggetto **/
  592. /** corrente rispetto al volume della visuale      **/
  593. /****************************************************/
  594. void clipobject3d(in)
  595. struct ambient3d *in;
  596. {
  597. long int n_z, f_z, curr_poly;
  598. long int x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4;
  599. long int x1_cmp, y1_cmp, x2_cmp, y2_cmp, x3_cmp, y3_cmp, x4_cmp, y4_cmp;
  600. long int vert0, vert1, vert2, vert3, fov_width, fov_height;
  601. struct objectnode *obj;
  602. struct vert1 *vc;
  603. struct polygon *pol;
  604.  
  605. obj=pobj(in);
  606.  
  607. vc=obj->vcamera;
  608. pol=obj->polys;
  609.  
  610. /* converto in fixpoint */
  611. n_z=in->near_z*FIXV;
  612. f_z=in->far_z*FIXV;
  613.  
  614. /*zvd=(in->viewing_distance*in->zoom)>>SFIXV;*/
  615.  
  616. if (in->clip_mode==ZPLANE)
  617.     {
  618. /* cerca di clippare ogni poligono con il volume della visuale */
  619.     for (curr_poly=0 ;curr_poly<obj->numpolys ;curr_poly++)
  620.         {
  621.     /* test di quanti lati */ 
  622.         switch(pol[curr_poly].numpoints)
  623.             {
  624.             case(1):
  625.                 z1=vc[pol[curr_poly].vertexlist0].z;
  626.                 z2=z1;
  627.                 z3=z1;
  628.                 z4=z4;
  629.                 break;
  630.  
  631.             case(2):
  632.                 z1=vc[pol[curr_poly].vertexlist0].z;
  633.                 z2=vc[pol[curr_poly].vertexlist1].z;
  634.                 z3=z2;
  635.                 z4=z2;
  636.                 break;
  637.  
  638.             case(3):
  639.                 z1=vc[pol[curr_poly].vertexlist0].z;
  640.                 z2=vc[pol[curr_poly].vertexlist1].z;
  641.                 z3=vc[pol[curr_poly].vertexlist2].z;
  642.                 z4=z3;
  643.                 break;
  644.  
  645.             case(4):
  646.                 z1=vc[pol[curr_poly].vertexlist0].z;
  647.                 z2=vc[pol[curr_poly].vertexlist1].z;
  648.                 z3=vc[pol[curr_poly].vertexlist2].z;
  649.                 z4=vc[pol[curr_poly].vertexlist3].z;
  650.                 break;
  651.             }
  652.  
  653.         if ((z1<n_z AND z2<n_z AND z3<n_z AND z4<n_z) OR
  654.            (z1>f_z AND z2>f_z AND z3>f_z AND z4>f_z))
  655.             pol[curr_poly].clipped=1;
  656.         }
  657.     }
  658. else
  659.     {
  660. /* FRUSTUM MODE CLIP */
  661.     /* calcolo i campi visivi in fixpoint */
  662. /*
  663.     fov_width=((in->half_screen_width)>>SFIXV)/zvd;
  664.     fov_height=(((in->half_screen_height)*in->inv_aspect_ratio) / zvd);
  665. */
  666. fov_width=in->fov_w;
  667. fov_height=in->fov_h;
  668.     for (curr_poly=0 ;curr_poly<obj->numpolys ;curr_poly++)        
  669.         {
  670.     /* test di quanti lati */
  671.         switch(pol[curr_poly].numpoints)
  672.             {
  673.             case(1):
  674.                 vert0=pol[curr_poly].vertexlist0;
  675.                 x1=vc[vert0].x;
  676.                 y1=vc[vert0].y;
  677.                 z1=vc[vert0].z;
  678.                 x2=x1;
  679.                 y2=y1;
  680.                 z2=z1;
  681.                 x3=x1;
  682.                 y3=y1;
  683.                 z3=z1;
  684.                 x4=x1;
  685.                 y4=y1;
  686.                 z4=z1;
  687.                 break;
  688.             case(2):
  689.                 vert0=pol[curr_poly].vertexlist0;
  690.                 vert1=pol[curr_poly].vertexlist1;
  691.                 x1=vc[vert0].x;
  692.                 y1=vc[vert0].y;
  693.                 z1=vc[vert0].z;
  694.                 x2=vc[vert1].x;
  695.                 y2=vc[vert1].y;
  696.                 z2=vc[vert1].z;
  697.                 x3=x2;
  698.                 y3=y2;
  699.                 z3=z2;
  700.                 x4=x2;
  701.                 y4=y2;
  702.                 z4=z2;
  703.                 break;
  704.             case(3):
  705.                 vert0=pol[curr_poly].vertexlist0;
  706.                 vert1=pol[curr_poly].vertexlist1;
  707.                 vert2=pol[curr_poly].vertexlist2;    
  708.                 x1=vc[vert0].x;
  709.                 y1=vc[vert0].y;
  710.                 z1=vc[vert0].z;
  711.                 x2=vc[vert1].x;
  712.                 y2=vc[vert1].y;
  713.                 z2=vc[vert1].z;
  714.                 x3=vc[vert2].x;
  715.                 y3=vc[vert2].y;
  716.                 z3=vc[vert2].z;
  717.                 x4=x3;
  718.                 y4=y3;
  719.                 z4=z3;
  720.                 break;
  721.             case(4):
  722.                 vert0=pol[curr_poly].vertexlist0;
  723.                 vert1=pol[curr_poly].vertexlist1;
  724.                 vert2=pol[curr_poly].vertexlist2;    
  725.                 vert3=pol[curr_poly].vertexlist3;
  726.                 x1=vc[vert0].x;
  727.                 y1=vc[vert0].y;
  728.                 z1=vc[vert0].z;
  729.                 x2=vc[vert1].x;
  730.                 y2=vc[vert1].y;
  731.                 z2=vc[vert1].z;
  732.                 x3=vc[vert2].x;
  733.                 y3=vc[vert2].y;
  734.                 z3=vc[vert2].z;
  735.                 x4=vc[vert3].x;
  736.                 y4=vc[vert3].y;
  737.                 z4=vc[vert3].z;
  738.                 break;
  739.             }
  740.         if (z1<n_z AND z2<n_z AND z3<n_z AND z4<n_z) 
  741.             {
  742.             pol[curr_poly].clipped=1;
  743.             continue;
  744.             }
  745.         if (z1>f_z AND z2>f_z AND z3>f_z AND z4>f_z)
  746.             {
  747.             pol[curr_poly].clipped=1;
  748.             continue;
  749.             }
  750.  
  751.         x1_cmp=(fov_width*z1) >> SFIXV;
  752.         x2_cmp=(fov_width*z2) >> SFIXV;
  753.         x3_cmp=(fov_width*z3) >> SFIXV;
  754.         x4_cmp=(fov_width*z4) >> SFIXV;
  755.  
  756.         if ((x1<-x1_cmp AND x2<-x2_cmp AND x3<-x3_cmp AND x4<-x4_cmp)
  757.            OR (x1>x1_cmp AND x2>x2_cmp AND x3>x3_cmp AND x4>x4_cmp))
  758.             {
  759.             pol[curr_poly].clipped=1;
  760.             continue;
  761.             }
  762.         y1_cmp=(fov_height*z1) >> SFIXV;
  763.         y2_cmp=(fov_height*z2) >> SFIXV;
  764.         y3_cmp=(fov_height*z3) >> SFIXV;
  765.         y4_cmp=(fov_height*z4) >> SFIXV;
  766.  
  767.         if ((y1<-y1_cmp AND y2<-y2_cmp AND y3<-y3_cmp AND y4<-y4_cmp)
  768.            OR (y1>y1_cmp AND y2>y2_cmp AND y3>y3_cmp AND y4>y4_cmp))
  769.             {
  770.             pol[curr_poly].clipped=1;
  771.             continue;
  772.             }
  773.         }
  774.     }
  775. }    
  776.  
  777. /*******************************************************************/
  778.